﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Toenda.Foundation.Utility {
	/// <summary>
	/// Struct PhoneNumber
	/// </summary>
	public class PhoneNumber {
		private string _countrycode;
		private string _areacode;
		private string _number;
		private string _raw;
		private PhoneNumberType _phoneNumberType;

		// ---------------------------------------------------
		// CONSTRUCTORS
		// ---------------------------------------------------

		/// <summary>
		/// Creates a new instance of <see cref="PhoneNumber"/>
		/// </summary>
		public PhoneNumber() {
		}

		/// <summary>
		/// Default Ctor
		/// </summary>
		/// <param name="rawNumber"></param>
		public PhoneNumber(string rawNumber) {
			this._raw = rawNumber;

			this._countrycode = "";
			this._areacode = "";
			this._number = "";
			this._phoneNumberType = PhoneNumberType.Unknown;
		}

		/// <summary>
		/// Default Ctor
		/// </summary>
		/// <param name="rawNumber"></param>
		/// <param name="type"></param>
		public PhoneNumber(string rawNumber, PhoneNumberType type) {
			this._raw = rawNumber;

			this._countrycode = "";
			this._areacode = "";
			this._number = "";
			this._phoneNumberType = type;
		}

		// ---------------------------------------------------
		// INTERFACE IMPLEMENTATIONS
		// ---------------------------------------------------

		// ---------------------------------------------------
		// PROPERTIES
		// ---------------------------------------------------

		/// <summary>
		/// Get or set the countrycode
		/// </summary>
		public string CountryCode {
			get { return this._countrycode + ""; }
			set { this._countrycode = value; }
		}

		/// <summary>
		/// Get or set the areacode
		/// </summary>
		public string AreaCode {
			get { return this._areacode + ""; }
			set { this._areacode = value; }
		}

		/// <summary>
		/// Get or set the number
		/// </summary>
		public string Number {
			get { return this._number + ""; }
			set { this._number = value; }
		}

		/// <summary>
		/// Get or set the raw number
		/// </summary>
		public string RawNumber {
			get { return this._raw + ""; }
			set {
				this._raw = value;

				// next time: parse number into number-items
				this._number = this._raw;

				//Regex preg = new Regex("/^[0-9-()/+.]*$/");
			}
		}

		/// <summary>
		/// Get or set the phone number type
		/// </summary>
		public PhoneNumberType PhoneNumberType {
			get { return this._phoneNumberType; }
			set { this._phoneNumberType = value; }
		}

		// ---------------------------------------------------
		// EVENTS
		// ---------------------------------------------------

		// ---------------------------------------------------
		// PRIVATE MEMBERS
		// ---------------------------------------------------

		// ---------------------------------------------------
		// PROTECTED MEMBERS
		// ---------------------------------------------------

		// ---------------------------------------------------
		// PUBLIC MEMBERS
		// ---------------------------------------------------

		/// <summary>
		/// Initialize a PhoneNumber object with a string
		/// </summary>
		/// <param name="value"></param>
		/// <returns></returns>
		public static implicit operator PhoneNumber(string value) {
			return new PhoneNumber(value);
		}

		/// <summary>
		/// Get this object as string
		/// </summary>
		/// <returns></returns>
		public override string ToString() {
			return this.FormatedPhoneNumber();
		}

		/// <summary>
		/// Get the complete phone number
		/// </summary>
		public string UnformatedPhoneNumber() {
			return this._countrycode
				+ this._areacode
				+ this._number;
		}

		/// <summary>
		/// Get the complete phone number
		/// </summary>
		public string FormatedPhoneNumber() {
			if(this._countrycode == null
			|| this._countrycode.Trim() != "") {
				return this._areacode
				+ "-"
				+ this._number;
			}
			else if(this._areacode == null
			|| this._areacode.Trim() == "") {
				return this._countrycode
				+ "-"
				+ this._number;
			}
			else if(( this._countrycode == null
			|| this._countrycode.Trim() != "" )
			&& ( this._areacode == null
			|| this._areacode.Trim() == "" )) {
				return this.UnformatedPhoneNumber();
			}
			else {
				return this._countrycode
				+ "-"
				+ this._areacode
				+ "-"
				+ this._number;
			}
		}

		/// <summary>
		/// Parse a number into a PhoneNumber
		/// </summary>
		/// <param name="rawNumber"></param>
		/// <returns></returns>
		public static PhoneNumber Parse(string rawNumber) {
			PhoneNumberParser parser = new PhoneNumberParser();
			return parser.ParseString(rawNumber);
		}
	}
}
